package com.seed.bpmn.rest;

import com.seed.bpmn.engine.IBPMNRuntimeService;
import com.seed.bpmn.engine.common.constants.BpmnConstants;
import com.seed.bpmn.engine.common.util.Empty;
import com.seed.bpmn.engine.common.util.ResultData;
import com.seed.bpmn.engine.dto.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSON;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(description = "运行级别流程数据操作接口")
@Controller
@RequestMapping("/bpmn/runtime")
public class RuntimeController {

    @Resource(name = "bpmnRuntimeService")
    private IBPMNRuntimeService runtimeService;

    @ApiOperation(value = "流程启动接口" ,
            notes = "流程启动接口，提交参数：processDefinitionId 流程定义Id，必填，businessKey 业务数据id,必填，userId 处理人，suggestio 启动意见")
    @RequestMapping(value = "/process-instance/start", method = RequestMethod.POST)
    @ResponseBody
    public JSON start(HttpServletRequest request) {
        ResultData data = new ResultData();
        try {
            String processDefinitionId = request.getParameter("processDefinitionId");
            String businessKey = request.getParameter("businessKey");
            String userId = request.getParameter("userId");
            String suggestion = request.getParameter("suggestion");
            String flows = request.getParameter("flows");
            String autoDraft = request.getParameter("autoDraft");
            String[] users = request.getParameterValues(BpmnConstants.ATTRIBUTE_TASK_USER_CANDIDATEUSERS);

            //防止序列化解析数据异常
            List<String> uList = new ArrayList<>();
            if(Empty.isNotEmpty(users)){
                for(String u : users){
                    uList.add(u);
                }
            }

            Map<String, Object> vs = new HashMap<String, Object>();
            vs.put(BpmnConstants.ATTRIBUTE_TASK_SUGGESTION, suggestion);
            vs.put(BpmnConstants.ATTRIBUTE_TASK_USER_CANDIDATEUSERS, uList);
            vs.put(BpmnConstants.ATTRIBUTE_TASK_USER_CANDIDATEGROUPS, new ArrayList<String>());

            initFlow(flows,vs);

            //是否需要完成自动创建的第一个环节的任务
            boolean autoComplete = "true".equals(autoDraft) ? true : false;

            ProcessInstanceStartDTO dto = this.runtimeService.start(processDefinitionId,businessKey, userId, vs, autoComplete);

            data = ResultData.success("操作成功", dto);
        } catch (Exception e) {
            e.printStackTrace();
            data = ResultData.failure("操作失败！" + e.getMessage());
        }
        return data.toJson();
    }

    @ApiOperation(value = "待办任务处理接口")
    @RequestMapping(value = "/task/complete", method = RequestMethod.POST)
    @ResponseBody
    public JSON complete(HttpServletRequest request) {
        ResultData data = new ResultData();
        try {

            String taskId = request.getParameter("taskId");
            String userId = request.getParameter("userId");
            String suggestion = request.getParameter("suggestion");
            String flows = request.getParameter("flows");
            String[] users = request.getParameterValues("candidateUsers");

            //防止序列化解析数据异常
            List<String> uList = new ArrayList<>();
            if(Empty.isNotEmpty(users)){
                for(String u : users){
                    uList.add(u);
                }
            }

            Map<String, Object> vs = new HashMap<String, Object>();

            vs.put(BpmnConstants.ATTRIBUTE_TASK_SUGGESTION, suggestion);
            vs.put(BpmnConstants.ATTRIBUTE_TASK_USER_CANDIDATEUSERS, uList);
            vs.put(BpmnConstants.ATTRIBUTE_TASK_USER_CANDIDATEGROUPS, new ArrayList<String>());

            initFlow(flows,vs);

            List<TaskEntityDTO> list = this.runtimeService.complete(taskId, userId, vs, false);

            data = ResultData.success("操作成功", list);
        } catch (Exception e) {
            data = ResultData.failure("操作失败！");
        }
        return data.toJson();
    }

    private void initFlow(String flows,Map<String, Object> vs){
        if (Empty.isNotEmpty(flows)) {
            String[] fs = flows.split(",");
            for (String flow : fs) {
                if (Empty.isNotEmpty(flow)) {
                    String[] f = flow.split("\\|");
                    if ("true".equals(f[1])) {
                        vs.put(f[0], true);
                    } else {
                        vs.put(f[0], false);
                    }
                }
            }
        }
    }

    @ApiOperation(value = "待办任务签收/取消签收接口")
    @RequestMapping(value = "/task/sign", method = RequestMethod.POST)
    @ResponseBody
    public JSON sign(HttpServletRequest request) {
        ResultData data = null;
        try {
            String taskId = request.getParameter("taskId");
            String userId = request.getParameter("userId");
            String isSign = request.getParameter("sign");

            boolean sign = false;
            if ("true".equals(isSign)) {
                sign = true;
            }

           this.runtimeService.sign(taskId, userId, sign);

            data = ResultData.success("操作成功",true);
        } catch (Exception e) {
            data = ResultData.failure("操作失败！");
        }
        return data.toJson();
    }

    @ApiOperation(value = "根据流程实例id获取待办任务接口")
    @RequestMapping(value = "/task/process-instance-id/{processInstanceId}", method = RequestMethod.GET)
    @ResponseBody
    public JSON findTaskByProcessInstanceId(@PathVariable String processInstanceId) {
        ResultData data = null;
        try {
            List<TaskDTO> list = this.runtimeService.findTaskByProcessInstanceId(processInstanceId);
            data = ResultData.success("操作成功", list);
        } catch (Exception e) {
            data = ResultData.failure("操作失败！");
        }
        return data.toJson();
    }

    @ApiOperation(value = "根据流程实例id、用户id获取待办任务接口")
    @RequestMapping(value = "/task/process-instance/{processInstanceId}/user/{userId}", method = RequestMethod.GET)
    @ResponseBody
    public JSON findTaskByProcessInstanceId(
            @PathVariable String processInstanceId,
            @PathVariable String userId) {
        ResultData data = null;
        try {
            List<TaskDTO> list = this.runtimeService.findTaskByProcessInstanceId(processInstanceId,
                userId);
            data = ResultData.success("操作成功", list);
        } catch (Exception e) {
            data = ResultData.failure("操作失败！");
        }
        return data.toJson();
    }

    @ApiOperation(value = "处理意见添加接口")
    @RequestMapping(value = "/comment/add", method = RequestMethod.POST)
    @ResponseBody
    public JSON addComment(HttpServletRequest request) {
        ResultData data = null;
        try {
            String taskId = request.getParameter("taskId");
            String userId = request.getParameter("userId");
            String processInstanceId = request.getParameter("processInstanceId");
            String suggestion = request.getParameter("suggestion");

            CommentDTO c = this.runtimeService.addComment(taskId, userId, processInstanceId,suggestion);

            if (Empty.isEmpty(c)) {
                data = ResultData.failure("操作失败！");
            } else {
                data = ResultData.success("操作成功", c);
            }
        } catch (Exception e) {
            data = ResultData.failure("操作失败！");
        }
        return data.toJson();
    }

    @ApiOperation(value = "流程调度接口")
    @RequestMapping(value = "/process/schedule", method = RequestMethod.POST)
    @ResponseBody
    public JSON schedule(HttpServletRequest request) {
        ResultData data = null;
        try {
            String processInstanceId = request.getParameter("processInstanceId");
            String nodeId = request.getParameter("nodeId");
            String[] users = request.getParameterValues(BpmnConstants.ATTRIBUTE_TASK_USER_CANDIDATEUSERS);
            String reason = request.getParameter("reason");

            List<String> uList = new ArrayList<>();
            if(Empty.isNotEmpty(users)){
                for(String u : users){
                    uList.add(u);
                }
            }

            ScheduleDTO s = this.runtimeService.scheduleProcess(processInstanceId, nodeId, uList,reason);

            if (Empty.isEmpty(s)) {
                data = ResultData.failure("操作失败！");
            } else {
                data = ResultData.success("操作成功", s);
            }
        } catch (Exception e) {
            data = ResultData.failure("操作失败！");
        }
        return data.toJson();
    }

    @ApiOperation(value = "删除流程实例接口")
    @RequestMapping(value = "/process/delete/{processInstanceId}/{reason}", method = RequestMethod.POST)
    @ResponseBody
    public JSON deleteProcessInstance(@PathVariable String processInstanceId, @PathVariable String reason) throws Exception {
        boolean flag = this.runtimeService.deleteProcessByInstanceId(processInstanceId,reason);
        ResultData data = ResultData.success("请求成功", flag);
        return data.toJson();
    }
}
